package cc.yaomm.common.basic.file;

import cc.yaomm.common.basic.base.SuperEnum;
import cc.yaomm.common.basic.exception.BusinessException;
import cc.yaomm.common.basic.file.properties.FileProperties;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.util.unit.DataSize;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

/**
 * Created by XQL on 2020/5/14.
 */
public interface FileService {

    Logger LOGGER = LoggerFactory.getLogger(FileService.class);

    /**
     * <p>@Description : 获取文件配置信息</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/19  </p>
     */
    FileProperties getFileProperties();

    /**
     * <p>@Description : 上传文件(不做大小格式限制)</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/15  </p>
     *
     * @param fileName  文件名
     * @param fileData  文件数据
     * @param directory 目录
     * @param isRewrite 是否重写文件名
     * @return
     */
    String upload(String fileName, byte[] fileData, SuperEnum<?, String> directory, boolean isRewrite);

    /**
     * <p>@Description : 删除单个文件</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/19  </p>
     *
     * @param filePath 文件路径
     * @return
     */
    boolean delete(String filePath);

    /**
     * <p>@Description : 批量删除文件</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/19  </p>
     *
     * @param filePathList 文件路径集合
     * @return
     */
    boolean delete(List<String> filePathList);

    /**
     * <p>@Description : 上传图片（验证格式、大小、压缩[依赖thumbnailator包]）</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/19  </p>
     *
     * @param fileName
     * @param fileData
     * @param directory
     * @param isRewrite 是否重写文件名
     * @return
     */
    default String uploadImage(String fileName, byte[] fileData, SuperEnum<?, String> directory, boolean isRewrite) {
        //获取配置文件
        FileProperties fileProperties = this.getFileProperties();
        String suffix = ".".concat(StringUtils.getFilenameExtension(fileName));

        //判断格式
        String imageFormat = fileProperties.getImage().getFormat();
        if (!StringUtils.isEmpty(imageFormat) && !imageFormat.contains(suffix)) {
            throw new BusinessException("图片格式不支持，支持格式：".concat(imageFormat));
        }

        //判断大小
        DataSize imageSize = fileProperties.getImage().getSize();
        if (imageSize != null && fileData.length > imageSize.toBytes()) {
            throw new BusinessException("图片大小超过限制，支持大小：".concat(imageSize.toString()));
        }

        //判断压缩
        DataSize compressSize = fileProperties.getImage().getCompress().getSize();
        if (fileProperties.getImage().getCompress().isEnable() && compressSize != null && fileData.length > compressSize.toBytes()) {
            try {
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                Thumbnails.of(new ByteArrayInputStream(fileData))
                        .scale(fileProperties.getImage().getCompress().getScale())
                        .outputQuality(fileProperties.getImage().getCompress().getQuality())
                        .toOutputStream(os);
                fileData = os.toByteArray();
            } catch (IOException e) {
                LOGGER.error("压缩图片异常，文件名：[{}]，文件大小：[{}]", fileName, fileData.length, e);
                throw new BusinessException("压缩图片异常", e);
            }
        }

        return this.upload(fileName, fileData, directory, isRewrite);
    }

    /**
     * <p>@Description : 上传音视频（验证格式、大小）</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/19  </p>
     *
     * @param fileName
     * @param fileData
     * @param directory
     * @param isRewrite
     * @return
     */
    default String uploadVideo(String fileName, byte[] fileData, SuperEnum<?, String> directory, boolean isRewrite) {
        //获取配置文件
        FileProperties fileProperties = this.getFileProperties();
        String suffix = ".".concat(StringUtils.getFilenameExtension(fileName));

        //判断格式
        String videoFormat = fileProperties.getVideo().getFormat();
        if (!StringUtils.isEmpty(videoFormat) && !videoFormat.contains(suffix)) {
            throw new BusinessException("音视频格式不支持，支持格式：".concat(videoFormat));
        }

        //判断大小
        DataSize videoSize = fileProperties.getVideo().getSize();
        if (videoSize != null && fileData.length > videoSize.toBytes()) {
            throw new BusinessException("音视频大小超过限制，支持大小：".concat(videoSize.toString()));
        }

        return this.upload(fileName, fileData, directory, isRewrite);
    }

    /**
     * <p>@Description : 上传其他文件（验证格式、大小）</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2020/5/19  </p>
     *
     * @param fileName
     * @param fileData
     * @param directory
     * @param isRewrite
     * @return
     */
    default String uploadOther(String fileName, byte[] fileData, SuperEnum<?, String> directory, boolean isRewrite) {
        //获取配置文件
        FileProperties fileProperties = this.getFileProperties();
        String suffix = ".".concat(StringUtils.getFilenameExtension(fileName));

        //判断格式
        String otherFormat = fileProperties.getOther().getFormat();
        if (!StringUtils.isEmpty(otherFormat) && !otherFormat.contains(suffix)) {
            throw new BusinessException("文件格式不支持，支持格式：".concat(otherFormat));
        }

        //判断大小
        DataSize otherSize = fileProperties.getOther().getSize();
        if (otherSize != null && fileData.length > otherSize.toBytes()) {
            throw new BusinessException("文件大小超过限制，支持大小：".concat(otherSize.toString()));
        }

        return this.upload(fileName, fileData, directory, isRewrite);
    }

    /**
     * <p>@Description: 构建文件名称</p>
     * <p>@Author: QiLin.Xing </p>
     * <p>@Date: 2020/5/17 16:28 </p>
     * <p>@Version: 1.0
     *
     * @param pathPrefix 路径前缀
     * @param fileName   文件名
     * @param isRewrite  是否重写文件名
     * @return
     */
    default String getFilePath(String pathPrefix, String fileName, boolean isRewrite) {
        StringBuffer filePathSb = new StringBuffer();
        Calendar now = Calendar.getInstance();
        filePathSb.append(pathPrefix).append(File.separator);
        filePathSb.append(now.get(Calendar.YEAR)).append(File.separator);
        filePathSb.append(now.get(Calendar.MONTH) + 1).append(File.separator);
        filePathSb.append(now.get(Calendar.DAY_OF_MONTH)).append(File.separator);

        //判断是否要重写文件名
        if (isRewrite) {
            String suffix = StringUtils.getFilenameExtension(fileName);
            filePathSb.append(UUID.randomUUID().toString().replaceAll("-", ""));
            filePathSb.append(".").append(suffix);
        } else {
            filePathSb.append(StringUtils.getFilename(fileName));
        }
        return filePathSb.toString();
    }
}
